package com.kyh.entity.base;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.web.context.ContextLoader;

import com.kyh.annotation.Model;

import tk.mybatis.mapper.util.StringUtil;

/**
*/
public class ConfBase<CONF, ENTITY> {
	
//	private static final Logger logger = Logger.getLogger(ConfBase.class);
	
	public static ApplicationContext ac = ContextLoader.getCurrentWebApplicationContext();
	
	public ENTITY e;
	
	public List<String> fields = new ArrayList<String>();
	
	private String field;
	
	private List<String> diyConfs= new ArrayList<String>();
	
	private List<String> leftJoins= new ArrayList<String>();
	
	public String groupBy;
	
	public OrderBy orderBy = new OrderBy();
	
	@SuppressWarnings("unchecked")
	public CONF eq(String name, Object value) {
		this.diyConfs.add("AND A." + name + " = '" + value + "' ");
		return (CONF) this;
	}
	
	@SuppressWarnings("unchecked")
	public CONF lt(String name, Object value) {
		this.diyConfs.add("AND A." + name + " < '" + value.toString() + "' ");
		return (CONF) this;
	}
	
	@SuppressWarnings("unchecked")
	public CONF ltEq(String name, String value) {
		this.diyConfs.add("AND A." + name + " <= '" + value + "' ");
		return (CONF) this;
	}
	
	@SuppressWarnings("unchecked")
	public CONF gt(String name, Object value) {
		this.diyConfs.add("AND A." + name + " > '" + value.toString() + "' ");
		return (CONF) this;
	}
	
	@SuppressWarnings("unchecked")
	public CONF gtEq(String name, String value) {
		this.diyConfs.add("AND A." + name + " >= '" + value + "' ");
		return (CONF) this;
	}
	
	@SuppressWarnings("unchecked")
	public CONF like(String name, String value) {
		this.diyConfs.add("AND A." + name + " like '" + value + "' ");
		return (CONF) this;
	}
	
	@SuppressWarnings("unchecked")
	public CONF where(String sql) {
		this.diyConfs.add(sql);
		return (CONF) this;
	}
	
	/**
	 * 左连接语句，示例：LEFT JOIN t_merchant B ON A.merchant_id = B.id
	 * @param sql
	 */
	@SuppressWarnings("unchecked")
	public CONF leftJoin(String sql) {
		this.leftJoins.add(sql);
		return (CONF) this;
	}
	
	public String getSqlConf() {
		
		StringBuffer sb = new StringBuffer("");
		
		
		// 拼接自定义搜索
		for (String sql : this.leftJoins) {
			sb.append(sql + " ");
		}
		
		sb.append("WHERE 1=1 ");
		
		Class<?> clazz = this.getClass();
		for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
			Field[] fields = clazz.getDeclaredFields();
			for (Field field : fields) {
				String name = field.getName();
				if (
						"orderBy".equals(name)
						|| "diyConfs".equals(name)
						|| "leftJoins".equals(name)
						|| "e".equals(name)
						|| "logger".equals(name)
//						|| "sqlSession".equals(name)
						|| "field".equals(name)
						|| "fields".equals(name)
						|| "groupBy".equals(name)
						|| "ac".equals(name)
						|| "isCount".equals(name)
						|| "dao".equals(name)
						) {
					continue;
				}
				if (!field.isAccessible()) {
					field.setAccessible(true);
				}
				try {
					Object value = field.get(this);
					if (value != null && !"".equals(value)) {
						sb.append("AND A." + StringUtil.camelhumpToUnderline(name) + " = '" + value + "' ");
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		
		// 拼接entity字段搜索
		if (this.e != null) {
			Field[] fields = this.e.getClass().getDeclaredFields();
			for (Field field : fields) {
				String name = field.getName();
				if (!field.isAccessible()) {
					field.setAccessible(true);
				}
				
				try {
					Model attrAnnotation = field.getAnnotation(Model.class);
					if (attrAnnotation == null) {
						continue;
					}
					Model.TYPE type = attrAnnotation.type();
					Object value = field.get(this.e);
					if (value != null && !"".equals(value)) {
						if (Model.TYPE.LEFT_JOIN.equals(type)) {
							sb.append("AND " + attrAnnotation.tableJoinName() + "." + attrAnnotation.colName() + " = '" + value + "' ");
						} else if (Model.TYPE.READ_ONLY.equals(type)) {
							continue;
						} else {
							sb.append("AND A." + StringUtil.camelhumpToUnderline(name) + " = '" + value + "' ");
						}
					} else {
						continue;
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		
		// 拼接groupBy
		if (this.groupBy != null && this.groupBy.length() > 0) {
			sb.append(this.groupBy + " ");
		}
		
		
		// 拼接自定义搜索
		for (String sql : this.diyConfs) {
			sb.append(sql + " ");
		}
		
		return sb.toString().replace("#", "").replace("{", "").replace("}", "");
	}
	
	public String getField() {
		if (field != null) {
			return this.field;
		}
		
		StringBuffer sb = new StringBuffer("");
		
		// 拼接field
		Field[] fieldArr = this.e.getClass().getDeclaredFields();
		for (Field field : fieldArr) {
			String name = field.getName();
			if (!field.isAccessible()) {
				field.setAccessible(true);
			}
			
			try {
				Model attrAnnotation = field.getAnnotation(Model.class);
				if (attrAnnotation == null) {
					continue;
				}
				Model.TYPE type = attrAnnotation.type();
				if (Model.TYPE.LEFT_JOIN.equals(type)) {
					sb.append(attrAnnotation.tableJoinName() + "." + attrAnnotation.colName() + " AS " + name + ",");
				} else if (Model.TYPE.SUM.equals(type) || Model.TYPE.READ_ONLY.equals(type)) {
					continue;
				} else {
					if (name.equals("key")) {
						sb.append("A.key AS `key`,");
					} else {
						sb.append("A." + StringUtil.camelhumpToUnderline(name) + " AS " + name + ",");
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		for (String str : fields) {
			sb.append(str + ",");
		}
		
		
		String fileds = sb.toString();
		int length = fileds.length();
		this.field = fileds.substring(0, length - 1);
		return this.field;
	}
	
	public String getOrderBy() {
		return this.orderBy.toString();
	}
}